package com.dianjing.dianjing.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.dianjing.dianjing.dto.input.UserCollectionInput;
import com.dianjing.dianjing.dto.output.PainterShowOutput;
import com.dianjing.dianjing.entity.Painting;
import com.dianjing.dianjing.entity.User;
import com.dianjing.dianjing.entity.UserCollection;
import com.dianjing.dianjing.enums.CollectionTypeEnum;
import com.dianjing.dianjing.enums.SysMessage;
import com.dianjing.dianjing.enums.UserTypeEnum;
import com.dianjing.dianjing.mapper.UserCollectionMapper;
import com.dianjing.dianjing.service.PaintingService;
import com.dianjing.dianjing.service.UserCollectionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dianjing.dianjing.service.UserService;
import com.dianjing.dianjing.util.MapUtil;
import com.dianjing.dianjing.util.ResponseData;
import jdk.nashorn.internal.ir.CallNode;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author owf
 * @since 2022-11-12
 */
@Service
public class UserCollectionServiceImpl extends ServiceImpl<UserCollectionMapper, UserCollection> implements UserCollectionService {

    @Autowired
    private PaintingService paintingService;

    @Autowired
    private UserService userService;
    /**
     * 收藏
     * @param input
     * @param type
     * @return
     */
    @Override
    public ResponseData collect(UserCollectionInput input, Integer type) {
        LambdaQueryWrapper<UserCollection> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserCollection::getUserId,input.getUserId())
                .eq(UserCollection::getCollectionId,input.getCollectionId())
                .eq(UserCollection::getType,type);
        UserCollection dbRecord = this.getBaseMapper().selectOne(queryWrapper);
        if (Objects.nonNull(dbRecord)) {
            return ResponseData.failed(SysMessage.DATA_IS_EXIST.getCode(),SysMessage.DATA_IS_EXIST.getMsg()).data(input);
        }
        UserCollection userCollection = MapUtil.map(input, UserCollection.class);
        userCollection.setType(type);
        this.save(userCollection);
        return ResponseData.success().data(userCollection);
    }

    @Override
    public Boolean worksCollect(Long userId, Long worksId) {
        // 直接添加收藏记录eme
        if(userId != null && worksId != null) {
            Boolean isCollected =  this.isCollected(CollectionTypeEnum.TYPE_PAINTING.getType(),userId,worksId);
            if (isCollected) {
                // 已经收藏
                return false;
            }
            UserCollection userCollection = new UserCollection();
            userCollection.setType(CollectionTypeEnum.TYPE_PAINTING.getType());
            userCollection.setCollectionId(worksId);
            userCollection.setUserId(userId);
            if(baseMapper.insert(userCollection) > 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否已经收藏
     * @param type
     * @param userId
     * @param worksId
     * @return
     */
    @Override
    public Boolean isCollected(Integer type, Long userId, Long worksId) {
        LambdaQueryWrapper<UserCollection> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollection::getType,type)
                .eq(UserCollection::getUserId,userId)
                .eq(UserCollection::getCollectionId,worksId);
        List<UserCollection> userCollections = baseMapper.selectList(wrapper);
        if (userCollections.size() > 0) {
            return true;
        }
        return false;
    }

    @Override
    public Boolean userCollect(Integer type, Long userId, Long objectId) {
        // 判断是否收藏自己
        if(type.equals(CollectionTypeEnum.TYPE_PAINTER.getType()) && userId.equals(objectId)) {
            // 不能收藏自己
            return false;
        }
        // 查看是否已经有收藏记录
        LambdaQueryWrapper<UserCollection> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollection::getType,type)
                .eq(UserCollection::getUserId,userId)
                .eq(UserCollection::getCollectionId,objectId);
        List<UserCollection> userCollections = baseMapper.selectList(wrapper);
        if(userCollections != null && userCollections.size() >= 1) {
            // 已经有收藏记录
            return false;
        }
        // 没有收藏记录，进行收藏
        UserCollection userCollection = new UserCollection();
        userCollection.setUserId(userId);
        userCollection.setType(type);
        userCollection.setCollectionId(objectId);
        baseMapper.insert(userCollection);
        return true;
    }

    @Override
    public List<PainterShowOutput> seeUserCollectPainter(Long userId,Integer typeId) {
        // 查询出用户收藏的所有画师
        LambdaQueryWrapper<UserCollection> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollection::getType,CollectionTypeEnum.TYPE_PAINTER.getType())
                .eq(UserCollection::getUserId,userId);
        List<UserCollection> userCollections = baseMapper.selectList(wrapper);
        // 得到收藏的所有画师id
        List<Long> painterIds = userCollections.stream().map(userCollection -> userCollection.getCollectionId()).collect(Collectors.toList());

        // 想要往下执行必须有画师id
        if(painterIds.isEmpty()) {
            return new ArrayList<>();
        }
        // 查询到所有画师的作品
        LambdaQueryWrapper<Painting> w = new LambdaQueryWrapper<>();
        w.in(Painting::getPainterId,painterIds);
        Collection<Painting> paintings = paintingService.list(w);

        // 将painterIds 对应为Map中的key
        HashMap<Long, List<Painting>> baseContainer = new HashMap<>(16);
        for (Long painterId : painterIds) {
            baseContainer.put(painterId,new ArrayList<Painting>());
        }
        // 将作品归到所属的画师下(对应Map的value)
        for (Painting painting : paintings) {
            Long painterId = painting.getPainterId();
            List<Painting> worksList = baseContainer.get(painterId);
            worksList.add(painting);
        }
        // 将Map转为List ，key变为 PainterShowOutput下的id，value就是下面的paintings
        Set<Long> mapKeys = baseContainer.keySet();
        List<PainterShowOutput> newContainer = mapKeys.stream().map(mapKey -> {
            PainterShowOutput newItem = new PainterShowOutput();
            newItem.setId(mapKey);
            newItem.setPaintings(baseContainer.get(mapKey));
            return newItem;
        }).collect(Collectors.toList());
        // 加入画师详细信息
        // 根据收藏的画师id集合批量获取画师的详细信息
        Collection<User> collectPainterData = userService.listByIds(painterIds);
        for (User userData : collectPainterData) {
            for (PainterShowOutput painterShowOutput : newContainer) {
                if(userData.getId().equals(painterShowOutput.getId())) {
                    BeanUtils.copyProperties(userData,painterShowOutput);
                }
            }
        }
        if(typeId == null) {
            // 如果typeId为空，不进行类型的筛选
            return newContainer;
        }
        // 进行筛选，找作品有指定类别的画家
        List<PainterShowOutput> finalContainer = new ArrayList<>();
        for (PainterShowOutput painterShowOutput : newContainer) {
            List<Painting> painterWorks = painterShowOutput.getPaintings();
            for (Painting painterWork : painterWorks) {
                if (painterWork.getType().equals(typeId)) {
                    // 如果作品有满足的类别，就下一个画师
                    finalContainer.add(painterShowOutput);
                    break;
                }
            }
        }
        return finalContainer;




    }

    @Override
    public List<Painting> seeUserCollectWorks(Long userId, Integer typeId) {
        // 查看用户收藏的作品id
        LambdaQueryWrapper<UserCollection> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollection::getUserId,userId)
                .eq(UserCollection::getType,CollectionTypeEnum.TYPE_PAINTING.getType());
        List<UserCollection> userCollections = baseMapper.selectList(wrapper);
        List<Long> paintingIds = userCollections.stream().map(collect -> collect.getCollectionId()).collect(Collectors.toList());

        // 批量查询为作品详情
        List<Painting> newContainer = paintingService.listByIds(paintingIds).stream().collect(Collectors.toList());
        // 收藏的作品类别必须满足typeId
        if(typeId == null) {
            // 没有传直接返回，不进行筛选
            return newContainer;
        }
        ArrayList<Painting> finalContainer = new ArrayList<>();
        for (Painting painting : newContainer) {
            if(typeId.equals(painting.getType()) ) {
                finalContainer.add(painting);
            }
        }
        return finalContainer;
    }

    @Override
    public Boolean cancelCollect(Integer type, Long userId, Integer collectId) {
        // 查看是否有满足的收藏记录
        LambdaQueryWrapper<UserCollection> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollection::getType,type)
                        .eq(UserCollection::getUserId,userId)
                        .eq(UserCollection::getCollectionId,collectId);
        List<UserCollection> userCollections = baseMapper.selectList(wrapper);
        if (userCollections != null && userCollections.size() >= 1) {
            // 有记录，那就删除==取消收藏
            int i = baseMapper.delete(wrapper);
            return i >= 1;
        }else {
            return false;
        }
    }


}
